<?php

namespace App\Service\Kms\Task;

use App\Enums\OpenShop\InvestmentPromotion\OrganizationManageEnum;
use App\Models\Kms\User\KmsUser;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationManageModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationManageUserModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageMappingModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageUserMappingModel;
use App\Service\BaseService;
use App\Service\OpenShop\Feishu\ConfigService;
use App\Service\OpenShop\Organization\WarZoneService;
use Closure;
use Illuminate\Support\Collection;
use Illuminate\Validation\ValidationException;

class UserRoleService extends BaseService
{
    const ROLE_SPECIAL_NO_ACCESS = -1;//无权限

    //特殊权限组
    const ROLE_SPECIAL_0 = 0;//所有权限
    const ROLE_SPECIAL_1 = 1;//大黄蜂
    const ROLE_SPECIAL_2 = 2;//赤瞳
    const ROLE_SPECIAL_3 = 3;//灵文
    const ROLE_SPECIAL_4 = 4;//辰月
    const ROLE_SPECIAL_5 = 5;//胖虎

    //基础权限组
    const ROLE_BASE_PROVINCE                   = 11;//省总
    const ROLE_BASE_SITE_SELECTION_DEVELOPMENT = 12;//选址开发
    const ROLE_BASE_SUPERVISOR                 = 13;//督导
    const ROLE_BASE_CITY_MANAGER               = 14;//城市经理
    const ROLE_BASE_PREPARE                    = 15;//筹备
    const ROLE_BASE_OBSERVER                   = 16;//观察者
    const ROLE_BASE_KAM                        = 17;//大客户经理
    const ROLE_BASE_WAR_REGION                 = 18;//战区负责人
    const ROLE_BASE_DEVELOP_CITY_MANAGER       = 19;// 开发城市经理

    const ROLE_TEXT = [
        self::ROLE_SPECIAL_NO_ACCESS               => "无权限",
        self::ROLE_SPECIAL_0                       => "超级管理员",
        self::ROLE_SPECIAL_1                       => "大黄蜂",
        self::ROLE_SPECIAL_2                       => "赤瞳",
        self::ROLE_SPECIAL_3                       => "灵文",
        self::ROLE_SPECIAL_4                       => "辰月",
        self::ROLE_SPECIAL_5                       => "胖虎",
        self::ROLE_BASE_PROVINCE                   => "省总",
        self::ROLE_BASE_SITE_SELECTION_DEVELOPMENT => "选址开发",
        self::ROLE_BASE_SUPERVISOR                 => "督导",
        self::ROLE_BASE_CITY_MANAGER               => "城市经理",
        self::ROLE_BASE_PREPARE                    => "筹备",
        self::ROLE_BASE_OBSERVER                   => "观察者",
        self::ROLE_BASE_KAM                        => "大客户经理",
        self::ROLE_BASE_WAR_REGION                 => "战区负责人",
        self::ROLE_BASE_DEVELOP_CITY_MANAGER       => '开发城市经理',
    ];

    /**
     * @param int $uid
     * @return array
     * @throws ValidationException
     */
    public static function getUserRole(int $uid): array
    {
        $userResponsibleArea   = [
            "all"      => true,
            "area"     => [
                "province" => [],
                "city"     => [],
                "district" => [],
            ],
            "fullArea" => [
                "province" => [],
                "city"     => [],
                "district" => []
            ]
        ];
        $role                  = self::checkSpecialRole($uid);
        $allOrganizationManage = OpenShopOrganizationManageModel::allOrganizationManage();
        $allRegionManage       = WarZoneService::regionTree();
        if (!empty($role)) {
            $role = $role["role"];
        } else {
            $role = self::getUserBaseRole($uid, $allRegionManage, $allOrganizationManage);
            $userResponsibleArea = self::getUserResponsibleArea(
                $uid, $allRegionManage, $allOrganizationManage
            );
        }

        return [
            "role"                => $role,
            "desc"                => self::ROLE_TEXT[$role] ?? "",
            "userResponsibleArea" => $userResponsibleArea,
            "homeBranchOffice"    => self::getKmsHomeBranchOffice($role, $uid, $allOrganizationManage),
            "warZone" => $allRegionManage->filter(
                function (OpenShopRegionManageModel $regionManageModel) use ($uid) {
                    $chargeUids = $regionManageModel->regionUserMappingRel->whereIn(
                        "type",
                        [
                            OpenShopRegionManageUserMappingModel::USER_TYPE_1,
                            OpenShopRegionManageUserMappingModel::USER_TYPE_2
                        ]
                    )->pluck("userId")->toArray();
                    if (in_array($uid, $chargeUids)) {
                        return true;
                    }
                    return false;
                })->map(function (OpenShopRegionManageModel $regionManageModel) {
                return $regionManageModel->only(["id", "name"]);
            })
        ];
    }


    /**
     * 获取用户可见区域
     *
     * @param int $uid
     * @param Collection $allRegionManage
     * @param Collection $allOrganizationManage
     * @return array
     */
    public static function getUserResponsibleArea(int $uid, Collection $allRegionManage, Collection $allOrganizationManage): array
    {
        $allPower     = false;
        $province     = $city = $district = [];
        $organizationIds = $fullProvince = $fullCity = $fullDistrict = [];

        $headquarters = $allOrganizationManage->where("type", OrganizationManageEnum::TYPE_HEADQUARTERS)->first();
        $operationAttacheUser = collect(json_decode($headquarters->operationAttacheUser, true));
        if ($headquarters->operationUid == $uid || in_array($uid, collect($operationAttacheUser)->pluck("uid")->toArray())) {
            $allPower = true;
        }

        if(!$allPower){
            $allRegionManage->each(function (OpenShopRegionManageModel $regionManageModel) use (&$organizationIds, $uid) {
                $isCharge = $regionManageModel->regionUserMappingRel->where("userId", $uid)->count();
                if($isCharge){
                    $organizationIds = array_merge(
                        $organizationIds,
                        $regionManageModel->regionMappingRel->pluck("manageId")->toArray()
                    );
                }
            });

            $allOrganizationManage->each(
                function (OpenShopOrganizationManageModel $organizationManageModel) use (
                    $uid,
                    &$allPower,
                    &$province,
                    &$city,
                    &$district,
                    &$fullProvince,
                    &$fullCity,
                    &$fullDistrict,
                    $organizationIds
                ) {
                    if ($organizationManageModel->type != OrganizationManageEnum::TYPE_HEADQUARTERS) {
                        $operationAttacheUser = collect(json_decode($organizationManageModel->operationAttacheUser,
                            true));
                        // todo 省总省份code导入 || 附属省总省份code导入 || 战区对应省区省份code导入
                        if (
                            $organizationManageModel->operationUid == $uid
                            ||
                            in_array($uid, collect($operationAttacheUser)->pluck("uid")->toArray())
                            ||
                            in_array($organizationManageModel->id, $organizationIds)
                        ) {
                            $province     = array_merge(
                                $province,
                                $organizationManageModel->regionRel->pluck("provinceCode")->toArray()
                            );
                            $fullProvince = array_merge(
                                $fullProvince,
                                $organizationManageModel->regionRel->pluck("provinceCode")->toArray()
                            );
                        }

                        $isSiteSelectionDevelopment = $organizationManageModel->managerUserRel
                            ->where("userId", $uid)
                            ->where("type", OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT)
                            ->count();

                        if ($isSiteSelectionDevelopment) { //选址开发
                            $province = array_merge(
                                $province,
                                $organizationManageModel->regionRel->pluck("provinceCode")->toArray()
                            );
                        }

                    //城市经理
                    $organizationManageModel->managerUserRel->where("userId", $uid)->whereIn("type", [
                        OpenShopOrganizationManageUserModel::TYPE_CITY_MANAGER,// 城市经理 - 运营城市经理
                        OpenShopOrganizationManageUserModel::TYPE_DEVELOP_CITY_MANAGER,// 开发城市经理
//                        OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT
                        ])->each(function (OpenShopOrganizationManageUserModel $manageUserModel) use (
                            &$province,
                            &$city,
                            &$district,
                            &$fullProvince,
                            &$fullCity,
                            &$fullDistrict
                        ) {
                            $addressCodesGroup = jsonToArr($manageUserModel->addressCodes ?? "", []);
                            foreach ($addressCodesGroup as $addressCode) {
                                $addressCodeArr = explode("-", $addressCode);
                                if (!empty($addressCodeArr[2])) {
                                    array_push($fullDistrict, $addressCodeArr);
                                    array_push($district, $addressCodeArr[2]);
                                } elseif (!empty($addressCodeArr[1])) {
                                    array_push($fullCity, $addressCodeArr);
                                    array_push($city, $addressCodeArr[1]);
                                }
                            }
                        });
                    }
                }
            );
        }


        return [
            "all"      => $allPower,
            "area"     => [
                "province" => array_values(array_unique($province)),
                "city"     => $city,
                "district" => $district
            ],
            "fullArea" => [
                "province" => $fullProvince,
                "city"     => $fullCity,
                "district" => $fullDistrict
            ]
        ];
    }


    /**
     * 获取首页可见下拉选项
     *
     * @param int $role
     * @param int $uid
     * @param Collection $allOrganizationManage
     * @return array
     */
    public static function getKmsHomeBranchOffice(int $role, int $uid, Collection $allOrganizationManage): array
    {
        $branchOffice           = $branchOfficeProvince = $branchOfficeCity = [];
        $isHeadOfficeAttachUser = false;

        $headOffice                     = $allOrganizationManage->where(
            "type", OpenShopOrganizationManageModel::HEADQUARTERS_ID
        )->first();
        $headOfficeOperationAttacheUser = collect(json_decode($headOffice->operationAttacheUser, true));
        if (in_array($uid, collect($headOfficeOperationAttacheUser)->pluck("uid")->toArray())) {
            $isHeadOfficeAttachUser = true;
        }

        $allOrganizationManage->where("type", "<>", OpenShopOrganizationManageModel::HEADQUARTERS_ID)->each(
            function (OpenShopOrganizationManageModel $organizationManageModel) use (
                $uid,
                $role,
                &$branchOffice,
                &$branchOfficeProvince,
                &$branchOfficeCity
            ) {
                // 省总 && 省总
                if ($organizationManageModel->operationUid == $uid && $role == self::ROLE_BASE_PROVINCE) {
                    array_push($branchOffice, $organizationManageModel->only(["id", "name"]));
                    $branchOfficeProvince = array_merge($branchOfficeProvince, $organizationManageModel->regionRel()->pluck("provinceCode")->toArray());
                }
                //附属省总省份code导入
                $operationAttacheUser = collect(json_decode($organizationManageModel->operationAttacheUser, true));
                if (in_array($uid, collect($operationAttacheUser)->pluck("uid")->toArray())) {
                    array_push($branchOffice, $organizationManageModel->only(["id", "name"]));
                    $branchOfficeProvince = array_merge($branchOfficeProvince, $organizationManageModel->regionRel()->pluck("provinceCode")->toArray());
                }

                //城市经理
                if ($organizationManageModel->managerUserRel->where("userId", $uid)->whereIn("type", [
                        OpenShopOrganizationManageUserModel::TYPE_CITY_MANAGER,
                    ])->count() && $role == self::ROLE_BASE_CITY_MANAGER) {
                    array_push($branchOffice, $organizationManageModel->only(["id", "name"]));
                    $organizationManageModel->managerUserRel->where('userId', $uid)->whereIn(
                        'type', [OpenShopOrganizationManageUserModel::TYPE_CITY_MANAGER]
                    )->each(function (OpenShopOrganizationManageUserModel $manageUserModel) use (&$branchOfficeProvince, &$branchOfficeCity) {
                        collect(jsonToArr($manageUserModel->addressCodes, []))
                            ->each(function ($address) use (&$branchOfficeProvince, &$branchOfficeCity) {
                                $addressArr = explode("-", $address);
                                array_push($branchOfficeProvince, $addressArr[0]);
                                array_push($branchOfficeCity, $addressArr[1]);
                            });
                    });
                }

                // 开发城市经理
                if ($organizationManageModel->managerUserRel->where('userId', $uid)->whereIn(
                        'type', [OpenShopOrganizationManageUserModel::TYPE_DEVELOP_CITY_MANAGER]
                    )->count() && $role == self::ROLE_BASE_DEVELOP_CITY_MANAGER) {
                    array_push($branchOffice, $organizationManageModel->only(['id', 'name']));
                    $organizationManageModel->managerUserRel->where('userId', $uid)->whereIn(
                        'type', [OpenShopOrganizationManageUserModel::TYPE_DEVELOP_CITY_MANAGER]
                    )->each(function (OpenShopOrganizationManageUserModel $manageUserModel) use (&$branchOfficeProvince, &$branchOfficeCity) {
                        collect(jsonToArr($manageUserModel->addressCodes, []))
                            ->each(function ($address) use (&$branchOfficeProvince, &$branchOfficeCity) {
                                $addressArr = explode("-", $address);
                                array_push($branchOfficeProvince, $addressArr[0]);
                                array_push($branchOfficeCity, $addressArr[1]);
                            });
                    });
                }

                //选址开发
                if ($organizationManageModel->managerUserRel->where("userId", $uid)->whereIn("type", [
                        OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT,
                    ])->count() && $role == self::ROLE_BASE_SITE_SELECTION_DEVELOPMENT) {
                    array_push($branchOffice, $organizationManageModel->only(["id", "name"]));
                    $branchOfficeProvince = array_merge($branchOfficeProvince, $organizationManageModel->regionRel()->pluck('provinceCode')->toArray());
                }
            }
        );

        return [
            "isHeadOfficeAttachUser" => $isHeadOfficeAttachUser,
            "branchOffice"           => $branchOffice,
            "branchOfficeProvince"   => $branchOfficeProvince,
            "branchOfficeCity"       => $branchOfficeCity
        ];
    }

    /**
     * @param int $uid
     * @return array
     * @throws ValidationException
     */
    public static function checkSpecialRole(int $uid): array
    {
        $specialRole = attributeGet(
            ConfigService::getConfigDetail("kms", "task.role"),
            "value",
            []
        );

        $userRole = collect($specialRole)->filter(function ($role) use ($uid) {
            if (in_array($uid, $role["userIds"])) {
                return true;
            }
            return false;
        })->values()->first();

        return collect($userRole)->only(["role", "desc"])->toArray();
    }

    /**
     * 区域类型分配角色校验
     *
     * @return Closure
     */
    public static function getRegionRoleFunc(): Closure
    {
        return function (Collection $allOrganizationManage, int $uid, int $type) {
            $role = self::ROLE_SPECIAL_NO_ACCESS;
            $allOrganizationManage->each(function (OpenShopOrganizationManageModel $organizationManageModel) use (
                $uid,
                $type,
                &$role
            ) {
                $manager = $organizationManageModel->managerUserRel
                    ->where("userId", $uid)
                    ->where("type", $type)
                    ->first();
                if ($manager) {
                    switch ($type) {
                        case OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER:
                            $role = self::ROLE_BASE_SUPERVISOR;
                            break;
                        case OpenShopOrganizationManageUserModel::TYPE_CITY_MANAGER:
                            $role = self::ROLE_BASE_CITY_MANAGER;
                            break;
                        case OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT:
                            $role = self::ROLE_BASE_SITE_SELECTION_DEVELOPMENT;
                            break;
                        case OpenShopOrganizationManageUserModel::TYPE_DEVELOP_CITY_MANAGER:// 开发城市经理
                            $role = self::ROLE_BASE_DEVELOP_CITY_MANAGER;
                            break;
                        default:
                            throw new \Exception("类型传参有误");
                    }
                    return false;
                }
            });
            return $role;
        };
    }

    /**
     * 校验大客户经理角色
     *
     * @param int $uid
     * @return int
     */
    public static function checkKamRole(int $uid): int
    {
        $exists = KmsUser::query()
                         ->where("rootDepartmentId", "od-667dab2538c92768b7098fbfc97c995e")
                         ->where("rmsUserId", $uid)->first();
        return $exists ? self::ROLE_BASE_KAM : self::ROLE_SPECIAL_NO_ACCESS;
    }

    /**
     *  获取战区总角色
     *
     * @param Collection $allRegionManage
     * @param int $uid
     * @return int
     */
    public static function getWarRegionRoleFunc(Collection $allRegionManage, int $uid): int
    {
        $role = self::ROLE_SPECIAL_NO_ACCESS;
        $allRegionManage->each(function (OpenShopRegionManageModel $regionManageModel) use (&$role, $uid) {
            $chargeUids = $regionManageModel->regionUserMappingRel->whereIn(
                "type",
                [
                    OpenShopRegionManageUserMappingModel::USER_TYPE_1,
                    OpenShopRegionManageUserMappingModel::USER_TYPE_2
                ]
            )->pluck("userId")->toArray();
            if (in_array($uid, $chargeUids)) {
                $role = self::ROLE_BASE_WAR_REGION;
                return false;
            }
        });
        return $role;
    }

    /**
     * 校验省总权限
     *
     * @return Closure
     */
    public static function getProvinceRoleFunc(): Closure
    {
        return function (Collection $allOrganizationManage, int $uid) {
            //省总
            $isProvince = $allOrganizationManage->where("operationUid", $uid)->first();
            if ($isProvince) {
                return self::ROLE_BASE_PROVINCE;
            }
            return self::ROLE_SPECIAL_NO_ACCESS;
        };
    }

    /**
     * 校验观察者权限
     *
     * @return Closure
     */
    public static function getObserverRoleFunc(): Closure
    {
        return function (Collection $allOrganizationManage, int $uid) {
            $role = self::ROLE_SPECIAL_NO_ACCESS;
            //附属省总
            $allOrganizationManage->each(function (OpenShopOrganizationManageModel $organizationManageModel) use (
                $uid,
                &$role
            ) {
                $operationAttacheUser = collect(json_decode($organizationManageModel->operationAttacheUser, true));
                if (in_array($uid, collect($operationAttacheUser)->pluck("uid")->toArray())) {
                    $role = self::ROLE_BASE_OBSERVER;
                    return false;
                }
            });
            return $role;
        };
    }

    /**
     * 判断筹备权限
     *
     * @return Closure
     */
    public static function getPrepareRoleFunc(): Closure
    {
        return function (Collection $allOrganizationManage, int $uid) {
            $isPrepare = $allOrganizationManage->where("preparationUid", $uid)->first();
            if ($isPrepare) {
                return self::ROLE_BASE_PREPARE;
            }
            return self::ROLE_SPECIAL_NO_ACCESS;
        };
    }

    /**
     * 判断基础权限
     *
     * @param int $uid
     * @param Collection $allRegionManage
     * @param Collection $allOrganizationManage
     * @return array|mixed|void
     */
    public static function getUserBaseRole(int $uid,Collection $allRegionManage, Collection $allOrganizationManage)
    {
        //todo 总部负责人 - 超级管理员
        $isHeadOffice = $allOrganizationManage->where("type", OrganizationManageEnum::TYPE_HEADQUARTERS)
                                              ->where("operationUid", $uid)
                                              ->first();

        if ($isHeadOffice) {
            return self::ROLE_SPECIAL_0;
        }

        // todo 战区总
        $role = self::getWarRegionRoleFunc($allRegionManage, $uid);
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 省总
        $role = self::getProvinceRoleFunc()($allOrganizationManage, $uid);
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 大客户经理
        $role = self::checkKamRole($uid);
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 选址开发
        $role = self::getRegionRoleFunc()(
            $allOrganizationManage,
            $uid,
            OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT
        );
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }


        //todo 督导
        $role = self::getRegionRoleFunc()(
            $allOrganizationManage,
            $uid,
            OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER
        );
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 城市经理 - 运营城市经理
        $role = self::getRegionRoleFunc()(
            $allOrganizationManage,
            $uid,
            OpenShopOrganizationManageUserModel::TYPE_CITY_MANAGER
        );
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 开发城市经理
        $role = self::getRegionRoleFunc()(
            $allOrganizationManage,
            $uid,
            OpenShopOrganizationManageUserModel::TYPE_DEVELOP_CITY_MANAGER
        );
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 筹备
        $role = self::getPrepareRoleFunc()($allOrganizationManage, $uid);
        if ($role > self::ROLE_SPECIAL_NO_ACCESS) {
            return $role;
        }

        //todo 观察者
        return self::getObserverRoleFunc()($allOrganizationManage, $uid);
    }
}
